package com.yunyao.framework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yunyao.common.constant.enums.AuditStatusEnums;
import com.yunyao.common.constant.enums.DataDeletedStatus;
import com.yunyao.common.constant.enums.DateFormatPattern;
import com.yunyao.common.constant.enums.InvoiceStatusStatus;
import com.yunyao.common.constant.enums.OrderStatus;
import com.yunyao.common.constant.enums.ReconciliationStatus;
import com.yunyao.common.constant.enums.SettlementStatus;
import com.yunyao.common.constant.enums.SupplyListStatus;
import com.yunyao.common.constant.enums.SupplyStatus;
import com.yunyao.common.core.BaseContext;
import com.yunyao.common.dto.excel.SupplyOrderExcelDto;
import com.yunyao.common.dto.order.SupplyOrderDto;
import com.yunyao.common.web.util.ConvertUtil;
import com.yunyao.common.web.util.PageResult;
import com.yunyao.common.web.util.YResult;
import com.yunyao.dao.mapper.BamuSupplyApplyMapper;
import com.yunyao.dao.model.BamuPoSupply;
import com.yunyao.dao.model.BamuPoSupplyMaterial;
import com.yunyao.dao.model.BamuPurchaseApply;
import com.yunyao.dao.model.BamuPurchaseApplyMaterial;
import com.yunyao.dao.model.BamuSoSupply;
import com.yunyao.dao.model.BamuSoSupplyMaterial;
import com.yunyao.dao.model.BamuSupplyApply;
import com.yunyao.dao.model.BamuSupplyApplyMaterial;
import com.yunyao.dao.service.bamu.IBamuAuditConfirmHistoryService;
import com.yunyao.dao.service.bamu.IBamuPoSupplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuPoSupplyService;
import com.yunyao.dao.service.bamu.IBamuPurchaseApplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuPurchaseApplyService;
import com.yunyao.dao.service.bamu.IBamuSoSupplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuSoSupplyService;
import com.yunyao.dao.service.bamu.IBamuSupplyApplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuSupplyApplyService;
import com.yunyao.framework.dto.supplyorder.SupplyOrderSaveDto;
import com.yunyao.framework.service.SupplyOrderService;
import com.yunyao.framework.vo.supplyorder.SupplyMaterialVO;
import com.yunyao.framework.vo.supplyorder.SupplyOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author chenyejian
 * @date 2024-07-16
 */
@Slf4j
@Service
public class SupplyOrderServiceImpl implements SupplyOrderService {
    @Autowired
    BamuSupplyApplyMapper bamuSupplyApplyMapper;
    private final String STATUS_AUDIT = "待云采确认";
    @Autowired
    private IBamuSupplyApplyService ibamuSupplyApplyService;
    @Autowired
    private IBamuPurchaseApplyService ibamuPurchaseApplyService;

    @Autowired
    private IBamuPurchaseApplyMaterialService iBamuPurchaseApplyMaterialService;

    @Autowired
    private IBamuSupplyApplyMaterialService iBamuSupplyApplyMaterialService;

    @Autowired
    private IBamuAuditConfirmHistoryService auditConfirmHistoryService;
    @Autowired
    private IBamuPoSupplyService iBamuPoSupplyService;
    @Autowired
    private IBamuSoSupplyService iBamuSoSupplyService;
    @Autowired
    private IBamuPoSupplyMaterialService iBamuPoSupplyMaterialService;
    @Autowired
    private IBamuSoSupplyMaterialService iBamuSoSupplyMaterialService;

    @Override
    public YResult<PageResult<SupplyOrderVO>> pageList(SupplyOrderDto projectOrderDto) {
        // 分页查询
        IPage<BamuSupplyApply> page = ibamuSupplyApplyService.pageListSupplyApply(projectOrderDto);
        List<BamuSupplyApply> supplyApplyList = page.getRecords();
        // 处理查询结果
        if (CollectionUtils.isEmpty(supplyApplyList)) {
            return YResult.success(new PageResult<>());
        }
        // 转换为VO对象列表
        List<SupplyOrderVO> voList = daoToVoList(supplyApplyList);

        // 返回分页结果
        return YResult.success(new PageResult<>(voList, page.getCurrent(), page.getSize(), page.getPages(), page.getTotal()));
    }

    @Override
    public YResult<SupplyOrderVO> getOrderDetailById(String id) {
        BamuSupplyApply apply = ibamuSupplyApplyService.getById(id);
        return YResult.success(dao2Vo(apply));
    }

    @Override
    public YResult<String> saveOrUpdate(SupplyOrderSaveDto projectOrderSaveDto) {
        try {
            BamuSupplyApply apply = saveDto2Dao(projectOrderSaveDto);
            if (ibamuSupplyApplyService.saveOrUpdate(apply)) {
                return YResult.success(apply.getId());
            }
        } catch (Exception e) {
            log.error("SupplyOrderServiceImpl.saveOrUpdate error", e);
        }
        return YResult.error("保存失败");
    }

    @Override
    public YResult<String> deleteByIds(String[] ids) {
        List<BamuSupplyApply> applyList = new ArrayList<>(ids.length);
        applyList = ibamuSupplyApplyService.listByIds(Arrays.asList(ids));
        for (BamuSupplyApply apply : applyList) {
            apply.setIsDeleted(DataDeletedStatus.YES.getType());
            apply.setUpdatedAt(new Date());
            apply.setUpdatedBy("test");
        }
        ibamuSupplyApplyService.saveOrUpdateBatch(applyList);
        return YResult.success("删除成功");
    }

    @Override
    public YResult<String> audit(SupplyOrderDto orderDto) {
        BamuSupplyApply apply = ibamuSupplyApplyService.getById(orderDto.getId());
        /**
         * 供货确认
         */
//        apply.setShipmentAt(new Date());
//        apply.setShipmentDesc(orderDto.getAuditReason());
//        apply.setShipmentFiles(orderDto.getAuditFileUrl());
//        apply.setShipmentUserId(BaseContext.getUserId());
//        apply.setShipmentUserName(BaseContext.getUserInfo().getRealName());
        /**
         * 确认通过
         */
        if (ConvertUtil.getIntValue(orderDto.getAuditStatus()) == AuditStatusEnums.AUDIT_SUCCESS.getType()) {
            apply.setSupplyConfirmDate(new Date());
//            apply.setSupplyConfirmFile(orderDto.getAuditFileUrl());
            apply.setSupplyStatus(SupplyStatus.SUPPLY_ING.getType());
        }
        /**
         * 确认通过
         */
        if (ConvertUtil.getIntValue(orderDto.getAuditStatus()) == AuditStatusEnums.AUDIT_REJECT.getType()) {
//            apply.setSupplyConfirmDate(new Date());
//            apply.setSupplyConfirmFile(orderDto.getAuditFileUrl());
            apply.setSupplyStatus(SupplyStatus.SUPPLIER_CONFIRMATION_REJECTED.getType());
        }

        /**
         * 同步状态到 purchaseApply
         */
        BamuPurchaseApply purchaseApply = ibamuPurchaseApplyService.getById(apply.getApplyId());
        if (purchaseApply != null) {
            purchaseApply.setSupplyStatus(apply.getSupplyStatus());
            purchaseApply.setSupplyConfirmDate(apply.getSupplyConfirmDate());
            purchaseApply.setSupplyConfirmFile((orderDto.getAuditFileUrl()));
            ibamuPurchaseApplyService.saveOrUpdate(purchaseApply);
        }

        auditConfirmHistoryService.insertRecord(apply.getId(), new Date(), null, orderDto.getAuditFileUrl(), orderDto.getAuditReason(), ConvertUtil.getIntValue(orderDto.getAuditStatus()), "0", BaseContext.getUserInfo().getRealName());
        ibamuSupplyApplyService.saveOrUpdate(apply);
        return YResult.success("审核成功");
    }

    /**
     * 供货接口
     *
     * @param saveDto
     * @return
     */
    @Transactional
    public YResult<String> saveposupply(SupplyOrderSaveDto saveDto) {
        // 根据SupplyOrderSaveDto中的id查询BamuSupplyApply
        /**
         * 供货订单
         */
        BamuSupplyApply supplyApply = ibamuSupplyApplyService.getById(saveDto.getId());
        if (supplyApply == null) {
            // 如果未找到对应的BamuSupplyApply，返回错误信息
            return YResult.error("未找到对应的供货单");
        }

        if (CollectionUtils.isEmpty(saveDto.getMaterialIdList())) {
            return YResult.error("请选择材料");
        }
        /**
         * 判断供货材料是否全部为0，全部为0不允许保存
         */
        Boolean isAllZero = true;
        for (SupplyMaterialVO materialvo : saveDto.getMaterialIdList()) {
            if (ConvertUtil.getBigDecimalValue(materialvo.getSupplyNum()).compareTo(BigDecimal.ZERO) > 0) {
                isAllZero = false;
                break;
            }
        }
        if (isAllZero) {
            return YResult.error("供货数量全部为0或剩余供货数量不足");
        }

        // 创建供货清单
        BamuPoSupply bamuPoSupply = new BamuPoSupply();
        BeanUtils.copyProperties(supplyApply, bamuPoSupply);
        bamuPoSupply.setId(null);
        bamuPoSupply.setShipmentAt(ConvertUtil.getString2Date(saveDto.getShipmentAt()));
        bamuPoSupply.setApplyId(supplyApply.getId());
        bamuPoSupply.setShipmentDesc(saveDto.getShipmentDesc());
        bamuPoSupply.setSupplyStatus(SupplyListStatus.UN_UPLOAD_ORDER.getType());
        bamuPoSupply.setContractId(supplyApply.getContractId());
        bamuPoSupply.setContractName(supplyApply.getContractName());
//        bamuPoSupply.setId(null);
        iBamuPoSupplyService.saveOrUpdate(bamuPoSupply);

        // 验收清单 关联 项目订单
        BamuPurchaseApply purchaseApply = ibamuPurchaseApplyService.getById(supplyApply.getApplyId());
        BamuSoSupply bamuSoSupply = new BamuSoSupply();
        BeanUtils.copyProperties(bamuPoSupply, bamuSoSupply);
        bamuSoSupply.setId(null);
        bamuSoSupply.setShipmentAt(ConvertUtil.getString2Date(saveDto.getShipmentAt()));
        bamuSoSupply.setApplyId(saveDto.getId());
        bamuSoSupply.setShipmentDesc(saveDto.getShipmentDesc());
        bamuSoSupply.setPoSupplyId(bamuPoSupply.getId());
        bamuSoSupply.setApplyId(purchaseApply.getId());
        bamuSoSupply.setSupplyStatus(SupplyListStatus.UN_UPLOAD_ORDER.getType());
        bamuSoSupply.setContractId(purchaseApply.getContractId());
        bamuSoSupply.setContractName(purchaseApply.getContractName());
//        bamuPoSupply.setId(null);
        iBamuSoSupplyService.saveOrUpdate(bamuSoSupply);
        // 批量保存或更新BamuPoSupplyMaterial信息
        saveMaterialIdList(saveDto.getMaterialIdList(), bamuPoSupply, bamuSoSupply);

        // 更新供应申请状态
        supplyApply.setSupplyStatus(SupplyStatus.SUPPLY_IN_PROGRESS.getType());
        ibamuSupplyApplyService.saveOrUpdate(supplyApply);

        // 更新采购申请状态
        if (purchaseApply != null) {
            purchaseApply.setSupplyStatus(SupplyStatus.SUPPLY_IN_PROGRESS.getType());
            ibamuPurchaseApplyService.saveOrUpdate(purchaseApply);
        }

        // 返回成功结果，携带BamuPoSupply的ID
        return YResult.success(bamuPoSupply.getId() + bamuSoSupply.getId());
    }

    @Override
    public YResult<SupplyMaterialVO> materialListCount(String orderId) {
        BamuSupplyApplyMaterial materialSum = iBamuSupplyApplyMaterialService.getTotalByOrderId(orderId);
        if (Objects.nonNull(materialSum)) {
            return YResult.success(convertDao2Vo(materialSum));
        }
        return YResult.success(new SupplyMaterialVO());
    }


    private void saveMaterialIdList(List<SupplyMaterialVO> materialIdList, BamuPoSupply bamuPoSupply, BamuSoSupply bamuSoSupply) {
        if (materialIdList != null && !materialIdList.isEmpty()) {
            LambdaQueryWrapper<BamuPurchaseApplyMaterial> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BamuPurchaseApplyMaterial::getPurchaseApplyId, bamuSoSupply.getApplyId()).eq(BamuPurchaseApplyMaterial::getIsDeleted, DataDeletedStatus.NO.getType());
            List<BamuPurchaseApplyMaterial> purchaseApplyMaterials = iBamuPurchaseApplyMaterialService.list(queryWrapper);
            Map<String, BamuPurchaseApplyMaterial> purchaseApplyMaterialMap = purchaseApplyMaterials.stream().collect(Collectors.toMap(BamuPurchaseApplyMaterial::getMaterialCode, Function.identity(), (a, b) -> a));
            for (SupplyMaterialVO materialvo : materialIdList) {
                if (ConvertUtil.getBigDecimalValue(materialvo.getExcludingTaxUnitPrice()).compareTo(BigDecimal.ZERO) == 0) {
                    BigDecimal includingTaxUnitPrice = ConvertUtil.getBigDecimalValue(materialvo.getIncludingTaxUnitPrice());
                    BigDecimal taxPrecent = ConvertUtil.getBigDecimalValue(materialvo.getTax()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
                    materialvo.setExcludingTaxUnitPrice(includingTaxUnitPrice.divide(BigDecimal.valueOf(1).add(taxPrecent), 4, RoundingMode.HALF_UP));
                }

                BamuPoSupplyMaterial poSupplyMaterial = new BamuPoSupplyMaterial();
                BeanUtils.copyProperties(materialvo, poSupplyMaterial);
                // 这里可以添加其他必要的属性设置
                poSupplyMaterial.setId(null);
                poSupplyMaterial.setSupplyId(bamuPoSupply.getId()); // 关联到BamuPoSupply
                poSupplyMaterial.setMaterialId(materialvo.getMaterialId()); // 设置材料ID
                poSupplyMaterial.setPurchaseApplyId(bamuPoSupply.getApplyId());
                poSupplyMaterial.setOrderMaterialId(materialvo.getOrderMaterialId());

                iBamuPoSupplyMaterialService.saveOrUpdate(poSupplyMaterial);


                /**
                 * 验收清单材料
                 */
                BamuSoSupplyMaterial soSupplyMaterial = new BamuSoSupplyMaterial();
                BeanUtils.copyProperties(materialvo, soSupplyMaterial);
                // 这里可以添加其他必要的属性设置
                soSupplyMaterial.setId(null);
                soSupplyMaterial.setSupplyId(bamuSoSupply.getId()); // 关联到BamuSoSupply
                soSupplyMaterial.setMaterialId(materialvo.getMaterialId()); // 设置材料ID
                soSupplyMaterial.setPoSupplyMaterialId(poSupplyMaterial.getId());
                soSupplyMaterial.setPurchaseApplyId(bamuSoSupply.getApplyId());
                setSoMaterialPrice(soSupplyMaterial, purchaseApplyMaterialMap);
                iBamuSoSupplyMaterialService.saveOrUpdate(soSupplyMaterial);
            }
        }
    }

    /**
     * 设置应收清单材料价格
     *
     * @param soSupplyMaterial         验收清单材料
     * @param purchaseApplyMaterialMap 采购申请材料
     * @return
     */
    private void setSoMaterialPrice(BamuSoSupplyMaterial soSupplyMaterial, Map<String, BamuPurchaseApplyMaterial> purchaseApplyMaterialMap) {
        if (purchaseApplyMaterialMap.containsKey(soSupplyMaterial.getMaterialCode())) {
            BamuPurchaseApplyMaterial purchaseApplyMaterial = purchaseApplyMaterialMap.get(soSupplyMaterial.getMaterialCode());
            soSupplyMaterial.setContractMaterialId(purchaseApplyMaterial.getContractMaterialId());
            soSupplyMaterial.setOrderMaterialId(purchaseApplyMaterial.getId());
            soSupplyMaterial.setExcludingTaxUnitPrice(purchaseApplyMaterial.getExcludingTaxUnitPrice());
            soSupplyMaterial.setIncludingTaxUnitPrice(purchaseApplyMaterial.getIncludingTaxUnitPrice());
            /**
             * 计算含税总价
             */
            soSupplyMaterial.setIncludingTaxTotalPrice(ConvertUtil.getBigDecimalValue(purchaseApplyMaterial.getIncludingTaxUnitPrice()).multiply(ConvertUtil.getBigDecimalValue(soSupplyMaterial.getSupplyNum())));

            soSupplyMaterial.setContractIncludingTaxPrice(purchaseApplyMaterial.getContractIncludingTaxPrice());
            soSupplyMaterial.setContractIncludingTaxTotalPrice(ConvertUtil.getBigDecimalValue(purchaseApplyMaterial.getContractIncludingTaxPrice()).multiply(ConvertUtil.getBigDecimalValue(soSupplyMaterial.getSupplyNum())));
        }
    }


    private List<SupplyOrderVO> daoToVoList(List<BamuSupplyApply> daoList) {
        List<SupplyOrderVO> voList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(daoList)) {
            return daoList.stream().map(this::dao2Vo).collect(Collectors.toList());
        }
        return voList;
    }

    /**
     * 转化并格式化
     *
     * @param apply
     * @return SupplyOrderVO
     */
    private SupplyOrderVO dao2Vo(BamuSupplyApply apply) {
        if (apply == null) {
            return new SupplyOrderVO();
        }
        SupplyOrderVO vo = new SupplyOrderVO();
        try {
            BeanUtils.copyProperties(apply, vo);
            StringBuffer status = new StringBuffer();
            String orderStatus = "";
            if ((apply.getSupplyStatus() == null || apply.getSupplyStatus() == 0) && ConvertUtil.getIntValue(apply.getAuditStatus(), -1) != AuditStatusEnums.AUDIT_SUCCESS.getType()) {
                orderStatus = AuditStatusEnums.getDescriptionByType(ConvertUtil.getIntValue(apply.getAuditStatus()));
            } else {
                if (apply.getSupplyStatus() == SupplyStatus.SUPPLY_COMPLETION_ACCEPTANCE.getType()) {
                    if (ConvertUtil.getIntValue(apply.getAuditStatus()) == AuditStatusEnums.AUDIT_REJECT.getType() || ConvertUtil.getIntValue(apply.getAuditStatus()) == AuditStatusEnums.AUDIT_REVOCATION.getType())
                        status.append(apply.getAuditStatus()).append("8");
                    orderStatus = OrderStatus.getDescriptionByType(status.toString());
                } else {
                    orderStatus = SupplyStatus.getDescriptionByType(apply.getSupplyStatus());
                }
            }
            /**
             * 审批中改为，待云采确认
             */
            if (orderStatus.equals(OrderStatus.APPROVAL_IN_PROGRESS.getDescription())) {
                orderStatus = STATUS_AUDIT;
            }
            vo.setOrderStatus(orderStatus);
            vo.setProjectInvoiceStatus(InvoiceStatusStatus.getDescriptionByType(apply.getProjectInvoiceStatus()));
            vo.setSupplyInvoiceStatus(InvoiceStatusStatus.getDescriptionByType(apply.getSupplyInvoiceStatus()));
            vo.setSettlementStatus(SettlementStatus.getDescriptionByType(apply.getSettlementStatus()));
            vo.setProjectReconciliationStatus(ReconciliationStatus.getDescriptionByType(apply.getProjectReconciliationStatus()));
            vo.setSupplierReconciliationStatus(ReconciliationStatus.getDescriptionByType(apply.getSupplierReconciliationStatus()));
//            vo.setCreatedAt(ConvertUtil.getFormatDate(apply.getCreatedAt(), false, DateFormatPattern.YEAR_MONTH_DAY.getPattern()));
            vo.setCopperDate(ConvertUtil.getFormatDate(apply.getCopperDate(), false, DateFormatPattern.YEAR_MONTH_DAY.getPattern()));
            vo.setReceivingTime(ConvertUtil.getFormatDate(apply.getReceivingTime(), false, DateFormatPattern.YEAR_MONTH_DAY.getPattern()));
            vo.setSupplyConfirmDate(ConvertUtil.getFormatDate(apply.getSupplyConfirmDate(), false, DateFormatPattern.YEAR_MONTH_DAY.getPattern()));
            vo.setTakeAt(ConvertUtil.getFormatDate(apply.getTakeAt(), false, DateFormatPattern.YEAR_MONTH_DAY.getPattern()));
            vo.setFlowSubmitDate(ConvertUtil.getFormatDate(apply.getFlowSubmitDate(), false, DateFormatPattern.YEAR_MONTH_DAY.getPattern()));
            vo.setTaxTotalPrice(apply.getTaxTotalPrice());
        } catch (Exception e) {
            log.error("SupplyOrderServiceImpl.daoToVo error", e);
        }
        return vo;
    }


    /**
     * projectOrderSaveDto 转 BamuSupplyApply
     */
    private BamuSupplyApply saveDto2Dao(SupplyOrderSaveDto projectOrderSaveDto) {
        BamuSupplyApply apply = new BamuSupplyApply();
        try {
            BeanUtils.copyProperties(projectOrderSaveDto, apply);
        } catch (Exception e) {
            log.error("SupplyOrderServiceImpl.voToDao error", e);
        }
        return apply;
    }


    private SupplyMaterialVO convertDao2Vo(BamuSupplyApplyMaterial bamuPurchaseApplyMaterial) {
        SupplyMaterialVO materialVO = new SupplyMaterialVO();
        BeanUtils.copyProperties(bamuPurchaseApplyMaterial, materialVO);
        return materialVO;
    }


    @Override
    public List<SupplyOrderExcelDto> export(SupplyOrderDto supplyOrderDto) {
        List<BamuSupplyApply> contractMaterialList = bamuSupplyApplyMapper.getSupplyApplyList(supplyOrderDto);
        if (CollectionUtils.isNotEmpty(contractMaterialList)) {
            return contractMaterialList.stream().map(this::convertToExcelDto).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    /**
     * 将BamuContractMaterial转化成ContractMaterialExportDto
     */
    private SupplyOrderExcelDto convertToExcelDto(BamuSupplyApply bamuPurchaseApply) {
        SupplyOrderExcelDto dto = new SupplyOrderExcelDto();
        BeanUtils.copyProperties(bamuPurchaseApply, dto);
        dto.setId(bamuPurchaseApply.getId());
        return dto;
    }

}
